const {
  app,
  BrowserWindow,
  Menu,
  screen,
  ipcMain,
  Tray,
  clipboard,
  dialog,
  Notification,
} = require("electron");
const fs = require("fs");
const { PosPrinter } = require("electron-pos-printer"); //下载时包有问题，而且优化后不使用这个包了，自己写
const path = require("node:path");
const windowConfigs = require("./plugins/windowConfigs");
const Datastore = require("node-persist");

/*========================================>( 公共方法 )<========================================*/
//缓存所在文件夹
const CacheDirPath = path.join(
  process.env.LOCALAPPDATA || process.env.PROGRAMFILES,
  "cache",
  "planb"
);

//检测并创建缓存文件夹
function initCacheDir() {
  fs.access(CacheDirPath, fs.constants.F_OK, (err) => {
    if (err) {
      //文件夹不存在
      fs.mkdir(CacheDirPath, { recursive: true }, (mkdirErr) => {
        if (mkdirErr) {
          console.error("创建缓存文件夹失败", mkdirErr);
          return;
        }
      });
    }
  });
}

// 初始化数据存储
async function initializePersist() {
  await Datastore.init({
    dir: CacheDirPath,
    // 其他配置...
  });
}
initializePersist();

// 存储数据
async function setData(key, value) {
  await Datastore.set(key, value);
}

// 检索数据
async function getData(key) {
  return await Datastore.get(key);
}

process.env["ELECTRON_DISABLE_SECURITY_WARNINGS"] = "true";

let _mainWindow, _screenWidth, _screenHeight;
let _browserWindows = {};
let _tomatoTask = undefined;
let _tomatoRemaining = undefined;
let _tomatoData = undefined;

const gotTheLock = app.requestSingleInstanceLock();
if (!gotTheLock) {
  app.quit();
}

//开启主窗口：按钮面板，贴边收起
function createWindow() {
  //关闭默认菜单栏
  Menu.setApplicationMenu(null);
  _mainWindow = new BrowserWindow({
    width: 66,
    height: 600,
    x: 0,
    y: (_screenHeight - 600) / 2,
    titleBarStyle: "hidden",
    resizable: false,
    movable: false,
    minimizable: false,
    maximizable: false,
    closable: false,
    alwaysOnTop: true,
    transparent: true,
    backgroundColor: "#00000000",
    webPreferences: {
      preload: path.join(__dirname, "preload.js"),
    },
  });
  _mainWindow.loadFile("index.html");
  _mainWindow.setSkipTaskbar(true);
  _mainWindow.on("close", () => {
    _mainWindow = null;
  });
  // _mainWindow.webContents.openDevTools()
}

//停止番茄钟
async function stopTomato() {
  clearInterval(_tomatoTask);
  _tomatoTask = undefined;
  _tomatoRemaining = undefined;
  const { time, date } = _tomatoData;
  const shouldSpace = time * 60 * 1000;
  const nowMils = new Date().getTime();
  const space = nowMils - date;
  let dataList = await getData("TOMATO_DATA_LIST");
  dataList = dataList ?? [];
  //筛选：去除昨天以前的数据
  const toDay = new Date();
  const year = toDay.getFullYear();
  const month = toDay.getMonth() + 1;
  const day = toDay.getDate();
  const butMils = new Date(`${year}-${month}-${day} 00:00:00`);
  dataList = dataList.filter((e) => e.date >= butMils);

  if (space - shouldSpace > 0 || Math.abs(space - shouldSpace) < 10000) {
    //顺利完成
    dataList.push({
      status: 1,
      time,
      date,
    });
  } else {
    //未完成
    dataList.push({
      status: 0,
      time,
      date,
      space,
    });
  }
  setData("TOMATO_DATA_LIST", dataList);
}

//ipc通讯监听
function ipcListener() {
  //保存番茄钟配置数据
  ipcMain.on("main-pad-setdata-tomato", function (event, arg) {
    const { setting, list } = arg;
    if (list) {
      setData("TOMATO_DATA_LIST", list);
    }
    if (setting) {
      setData("TOMATO_DATA_SETTING", setting);
    }
  });
  //获取番茄钟配置数据
  ipcMain.on("main-pad-getdata-tomato", async function (event, arg) {
    const key = arg;
    let data = await getData(key);
    if (key == "TOMATO_DATA_LIST") {
      data = data ?? []
      //筛选：去除昨天以前的数据
      const toDay = new Date();
      const year = toDay.getFullYear();
      const month = toDay.getMonth() + 1;
      const day = toDay.getDate();
      const butMils = new Date(`${year}-${month}-${day} 00:00:00`);
      data = data.filter((e) => e.date >= butMils);
    }
    if (key == "TOMATO_DATA_SETTING") {
      data = data ?? { time: 40 };
    }
    event.reply("tomato-data", { key, data });
  });
  //监听开始番茄钟计时
  ipcMain.on("main-pad-set-tomato", function (event, arg) {
    //如果存在任务则清除
    if (_tomatoTask) {
      console.log("番茄钟报错：已有未完成的番茄钟");
      return;
    }
    const { remaining, tomatoData } = arg;
    _tomatoData = tomatoData;
    _tomatoRemaining = remaining;
    console.log("番茄钟开始计时", _tomatoRemaining);
    _tomatoTask = setInterval(() => {
      _tomatoRemaining -= 1000;
      if (_tomatoRemaining <= 0) {
        //计时结束，清空，并通知
        new Notification({
          title: "番茄钟停止",
          body: "您可以休息一会儿，伸伸懒腰，身体是革命的本钱。",
          urgency: "critical",
          timeoutType: "never",
          icon: path.join(__dirname, "assets/PlantB.ico"),
        }).show();
        stopTomato();
      }
    }, 1000);
  });
  //监听返回番茄钟计时
  ipcMain.on("main-pad-get-tomato", function (event, arg) {
    event.reply("tomato", _tomatoRemaining);
  });
  //监听停止番茄钟计时
  ipcMain.on("main-pad-stop-tomato", function (event, arg) {
    stopTomato();
  });
  //监听清空今日番茄
  ipcMain.on("main-pad-clearlist-tomato", function (event, arg) {
    setData("TOMATO_DATA_LIST", []);
  });
  //监听获取打印机列表
  ipcMain.on("main-pad-get-printers", async function (event, arg) {
    const list = await _mainWindow.webContents.getPrintersAsync();
    event.reply("printers", list);
  });
  //使用打印机进行打印
  ipcMain.on("main-pad-print", function (event, arg) {
    const { preview, imagePath, printerName, paperType, iw, ih, border } = arg;
    const pageOp = {
      A4: {
        pageSize: { width: 793, height: 1121 },
      },
      A5: {
        pageSize: { width: 559, height: 793 },
      },
      A6: {
        pageSize: { width: 396, height: 559 },
      },
    };
    const pageSize = pageOp[paperType].pageSize;

    //按比例计算图像像素长宽
    //要保证图像完全显示在纸张内
    //计算像素小一些保证不超出
    //先计算实际打印区间的宽高
    let contentWith;
    let contentHeight;
    let printBorderTop = 0;
    switch (border) {
      case 1:
        //边距为小边距，宽高减少50px,
        contentWith = pageSize.width - 50;
        contentHeight = pageSize.height - 50;
        printBorderTop = 18;
        break;
      case 2:
        //边距为小边距，宽高减少100px,
        contentWith = pageSize.width - 100;
        contentHeight = pageSize.height - 100;
        printBorderTop = 42;
        break;
      default:
        contentWith = pageSize.width - 20;
        contentHeight = pageSize.height - 20;
        printBorderTop = 6;
        break;
    }

    const imageRate = iw / ih;
    const paperRate = contentWith / contentHeight;

    if (imageRate > paperRate) {
      //图像的宽占比大
      imageWPx = contentWith - 5;
      imageHPx = (imageWPx * ih) / iw;
    } else {
      //纸张的高占比大
      imageHPx = contentHeight - 5;
      imageWPx = (imageHPx * iw) / ih;
    }

    // const filePath = `C:/Users/Enphy/Desktop/微信截图_20241119164127.png`;
    const options = {
      preview, // Preview in window or print
      silent: !preview,
      margins: { top: printBorderTop }, // margin of content body
      copies: 1, // Number of copies to print
      printerName, // printerName: string, check with webContent.getPrinters()
      timeOutPerLine: 400,
      pageSize, // 根据纸张尺寸，限制px大小
    };

    const data = [
      {
        type: "image",
        // path: path.join(__dirname, "assets/img/collocation/1.jpg"), // file path
        path: imagePath,
        position: "center", // position of image: 'left' | 'center' | 'right'
        width: `${imageWPx}px`, // width of image in px; default: auto //根据图像比例和纸张尺寸进行计算
        height: `${imageHPx}px`, // width of image in px; default: 50 or '50px'
        style: {
          paddingTop: printBorderTop + "px",
        },
      },
    ];
    PosPrinter.print(data, options);
  });
  //监听选择路径并储存
  ipcMain.on("main-pad-file-save", function (event, arg) {
    const { title, defaultPath, data } = arg;
    dialog
      .showSaveDialog({
        title,
        buttonLabel: "保存",
        defaultPath, // 默认文件名
        filters: [{ name: "JPG Files", extensions: ["jpg"] }],
      })
      .then(({ filePath }) => {
        if (filePath) {
          const buffer = Buffer.from(data.replace(/^.*base64,/, ""), "base64");
          fs.writeFile(filePath, buffer, (err) => {
            if (err) {
              console.log("保存图片错误", err);
              return;
            }
            dialog.showMessageBox({
              title: "提示",
              message: "保存成功",
              detail: "已经保存至" + filePath,
            });
          });
        }
      });
  });
  //监听保存图片缓存
  ipcMain.on("main-pad-cache-save", function (event, arg) {
    const { defaultPath, data } = arg;
    const buffer = Buffer.from(data.replace(/^.*base64,/, ""), "base64");
    const filePath = path.join(CacheDirPath, defaultPath);
    fs.writeFile(filePath, buffer, (err) => {
      if (err) {
        console.log("保存缓存错误", err);
        return;
      }
      event.reply("printerFilePath", filePath);
    });
  });
  //监听剪贴板操作
  ipcMain.on("main-pad-clipboard", function (event, arg) {
    const { type, value } = arg;
    if (type == "text") {
      clipboard.writeText(value);
    }
  });
  //监听pad隐藏显示
  ipcMain.on("main-pad-hide-show", function (event, arg) {
    _mainWindow.setBounds({ x: arg === "hide" ? -60 : 0 }, true);
  });
  //监听打开新窗口
  ipcMain.on("main-pad-open-window", async function (event, arg) {
    if (!arg) {
      return;
    }
    let window = _browserWindows[arg];
    if (window) {
      //如果目标窗口已经开启，则激活显示
      if (window.isMinimized()) {
        window.restore();
      }
      window.focus();
      window.show();
      return;
    }
    let { config, localpath, dev } = windowConfigs[arg];
    config.width = config.width || _screenWidth;
    config.height = config.height || _screenHeight;
    let browserWindow = new BrowserWindow({
      ...config,
      webPreferences: {
        preload: path.join(__dirname, "preload.js"),
      },
    });
    browserWindow.loadFile(localpath);
    if (dev) {
      browserWindow.webContents.openDevTools();
    }
    browserWindow.on("close", () => {
      _browserWindows[arg] = null;
    });
    _browserWindows[arg] = browserWindow;
  });
}

function initTray() {
  tray = new Tray(path.join(__dirname, "assets/PlantB.ico"));
  const contextMenu = Menu.buildFromTemplate([
    {
      label: "退出",
      click: () => {
        app.exit();
      },
    },
  ]);
  tray.setToolTip("PlantB");
  tray.setContextMenu(contextMenu);
}

//程序环境准备好时触发
app.whenReady().then(() => {
  //获取屏幕宽高
  _screenWidth = screen.getPrimaryDisplay().bounds.width;
  _screenHeight = screen.getPrimaryDisplay().bounds.height;
  createWindow();
  ipcListener();
  //程序被激活，如果目前没有窗口，则创建主窗口
  app.on("activate", function () {
    if (BrowserWindow.getAllWindows().length === 0) createWindow();
  });
  initTray();
  initCacheDir();
});

app.on("ready", function () {});

//如果所有的窗口都关闭
app.on("window-all-closed", function () {
  if (process.platform !== "darwin") app.quit();
});

app.setAppUserModelId("PlanB");

//其他
const isDevelopment = !app.isPackaged;
if (isDevelopment) {
  try {
    require("electron-reloader")(module);
  } catch (err) {}
}
